const {
	ENUM_LOG_LEVEL,
	ENUM_LOG_TYPE
} = require("../../static/enum");
const NotificationCenter = require("../notificationCenter/index");
const Utils = require("../utils/index");
const LogData = require("./logData");

// 初始化日志中心

let NOTIFICATION_LOGDATA_CHANGE = 'LOGDATA_CHANGE';
let TEMP_LOG_DATA = [];
const STORAGE_KEY_LOGDATA = 'logData';

// 注册日志中心
// 获取本地存储中的日志数据
const storageLogData = uni.getStorageSync(STORAGE_KEY_LOGDATA);
// 如果本地存储中有日志数据
if (storageLogData) {
	// 过滤出最近一周的日志数据
	TEMP_LOG_DATA = storageLogData.filter(item => {
		return item.time > new Date().getTime() - 1000 * 60 * 60 * 24 * 3; // 只保留最近一周的日志
	});
} else {
	// 如果本地存储中没有日志数据，则初始化为空数组
	TEMP_LOG_DATA = [];
}
// 将过滤后的日志数据存储到本地存储中
uni.setStorageSync(STORAGE_KEY_LOGDATA, TEMP_LOG_DATA);

// 同步获取日志数据
function getLogDataSync() {
	return TEMP_LOG_DATA;
}

// 异步获取日志数据
function getLogDataAsync(callback) {
	let observerSymbol = `LOGDATA_CHANGE-${Utils.Util.getUUID()}`;
	typeof callback === 'function' && callback(TEMP_LOG_DATA);
	NotificationCenter.addNormalNotificationObserver(NOTIFICATION_LOGDATA_CHANGE, (data) => {
		typeof callback === 'function' && callback(data);
	}, observerSymbol);
	return observerSymbol;
}

// 函数removeLogDataWatcher用于移除观察者
function removeLogDataWatcher(observerSymbol) {
	// 调用NotificationCenter.removeNotificationObserver函数，传入NOTIFICATION_LOGDATA_CHANGE和observerSymbol作为参数
	NotificationCenter.removeNotificationObserver(NOTIFICATION_LOGDATA_CHANGE, observerSymbol);
}

// 声明一个变量，用于存储定时器ID
let _timeoutId = null;
// 定义一个常量，用于规定存储日志级别
const _storageLogLevel = Object.values(ENUM_LOG_LEVEL).filter(item => item !== ENUM_LOG_LEVEL.INFO)

// 定义一个函数，用于改变临时日志数据
function changeTempLogData(logData) {
	// 将传入的日志数据添加到临时日志数据数组中
	TEMP_LOG_DATA.push(logData);
	// 如果定时器ID存在，则清除定时器
	if (_timeoutId) {
		clearTimeout(_timeoutId);
		_timeoutId = null;
	}
	// 设置一个定时器，延迟400毫秒后执行
	_timeoutId = setTimeout(() => {
		// 将临时日志数据保存到本地存储中
		uni.setStorageSync(STORAGE_KEY_LOGDATA, TEMP_LOG_DATA.filter(item => {
			return _storageLogLevel.includes(item.level);
		}));
		// 发送一个通知，通知日志数据已经改变
		NotificationCenter.postNotification(NOTIFICATION_LOGDATA_CHANGE, TEMP_LOG_DATA);
		// 清除定时器
		clearTimeout(_timeoutId);
		_timeoutId = null;
	}, 400)
}

function log(...msg) {
	_logAction(ENUM_LOG_LEVEL.INFO, ...msg);
}

// 定义一个logDebug函数，用于记录调试信息
function logDebug(...msg) {
	_logAction(ENUM_LOG_LEVEL.DEBUG, ...msg);
}

// 定义一个logInfo函数，用于记录信息
function logInfo(...msg) {
	_logAction(ENUM_LOG_LEVEL.INFO, ...msg);
}

// 定义一个logWarn函数，用于记录警告
function logWarn(...msg) {
	_logAction(ENUM_LOG_LEVEL.WARN, ...msg);
}

// 定义一个logError函数，用于记录错误
function logError(...msg) {
	_logAction(ENUM_LOG_LEVEL.ERROR, ...msg);
}

function _logAction(logLevel=ENUM_LOG_LEVEL.INFO, ...msg) {
	let consoleFn;
	switch(logLevel) {
		case ENUM_LOG_LEVEL.DEBUG:
			consoleFn = console.debug;
			break;
		case ENUM_LOG_LEVEL.WARN:
			consoleFn = console.warn;
			break;
		case ENUM_LOG_LEVEL.ERROR:
			consoleFn = console.error;
			break;
		case ENUM_LOG_LEVEL.INFO:
			consoleFn = console.info;
			break;
		default:
			consoleFn = console.log;
			break;
	}
	consoleFn && consoleFn(...msg);
	let logType = ENUM_LOG_TYPE.OTHER_LOG;
	let typeList = Object.values(ENUM_LOG_TYPE);
	if (msg && msg.length > 0 && typeList.includes(msg[0])) {
		logType = msg.shift();
	}
	if (typeof msg == 'object') msg = JSON.stringify(msg);
	changeTempLogData(new LogData(logLevel, logType, msg));
}

// 微信统计日志
let _logWXRealtimeFn;
// #ifndef MP-WEIXIN
let wx;
// #endif
if (wx && typeof wx.getRealtimeLogManager == 'function') {
	let _wxLogManager = wx.getRealtimeLogManager();
	if (_wxLogManager) {
		_logWXRealtimeFn = function(logLevel=ENUM_LOG_LEVEL.INFO, ...msg) {
			switch(logLevel) {
				case ENUM_LOG_LEVEL.DEBUG:
					_wxLogManager.debug.apply(_wxLogManager, msg);
					break;
				case ENUM_LOG_LEVEL.WARN:
					_wxLogManager.warn.apply(_wxLogManager, msg);
					break;
				case ENUM_LOG_LEVEL.ERROR:
					_wxLogManager.error.apply(_wxLogManager, msg);
					break;
				case ENUM_LOG_LEVEL.INFO:
					_wxLogManager.info.apply(_wxLogManager, msg);
					break;
				default:
					_wxLogManager.log.apply(_wxLogManager, msg);
					break;
			}
		}
	}
} 
if (!_logWXRealtimeFn) {
	_logWXRealtimeFn = _logAction;
}
function logWXRealtime(...msg) {
	_logWXRealtimeFn(ENUM_LOG_LEVEL.INFO, ...msg);
}
function logInfoWXRealtime(...msg) {
	_logWXRealtimeFn(ENUM_LOG_LEVEL.INFO, ...msg);
}

function logDebugWXRealtime(...msg) {
	_logWXRealtimeFn(ENUM_LOG_LEVEL.DEBUG, ...msg);
}

function logWarnWXRealtime(...msg) {
	_logWXRealtimeFn(ENUM_LOG_LEVEL.WARN, ...msg);
}

function logErrorWXRealtime(...msg) {
	_logWXRealtimeFn(ENUM_LOG_LEVEL.ERROR, ...msg);
}


module.exports = {

	getLogDataSync,
	getLogDataAsync,
	removeLogDataWatcher,

	logInfo,
	logError,
	logWarn,
	logDebug,

	logWXRealtime,
	logInfoWXRealtime,
	logDebugWXRealtime,
	logWarnWXRealtime,
	logErrorWXRealtime
}